package com.ehotting.mqbd.zw.netty.call;

import com.ehotting.eaf.core.utils.AssertUtils;
import com.ehotting.edsta.mqbd.api.enums.SysModuleEnum;
import com.ehotting.mqbd.api.MqDataStateConstants;
import com.ehotting.mqbd.api.bean.MQDataAble;
import com.ehotting.mqbd.api.bean.solver.SolverInfoBean;
import com.ehotting.mqbd.api.bean.solver.SolverStateBean;
import com.ehotting.mqbd.api.exception.CallException;
import com.ehotting.mqbd.api.exception.TcpException;
import com.ehotting.mqbd.core.call.CallerAbstract;
import com.ehotting.mqbd.zw.api.bean.ZwMQTcpData;
import com.ehotting.mqbd.zw.api.constants.ActionConstants;
import com.ehotting.mqbd.zw.api.domain.netty.ZwCommPacket;
import com.ehotting.mqbd.zw.netty.netty.ZwTcpClient;
import com.ehotting.mqbd.zw.netty.netty.ZwTcpMultiClient;
import com.ehotting.mqbd.zw.netty.service.ZwMsgStateHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class MQZwNettyCaller extends CallerAbstract {

    public static Logger logger = LoggerFactory.getLogger(MQZwNettyCaller.class);

    @Autowired
    private ZwTcpMultiClient zwTcpMultiClient;


    @Override
    public void doAction(SolverStateBean serverState, MQDataAble data) {
        logger.info("Start doAction.");

        ZwMQTcpData tcpData = (ZwMQTcpData) data;

        ZwCommPacket response =  sendZwPkg(tcpData.getRequest(),data.getModule(),data.getAgentId(),serverState.getSolverInfo());
        if(response!=null) {
            tcpData.setResponse(response);
        }

        logger.info("Finish doAction.");
    }

    @Override
    public void validData(MQDataAble data) {

        AssertUtils.isTrue(data instanceof ZwMQTcpData,
                new CallException(MqDataStateConstants.CONVERT_ERROR,"data not instanceof ZwMQTcpData"));


        ZwMQTcpData tcpData = (ZwMQTcpData)data;
        if(tcpData.getRequest().getHead().getCmd() == ActionConstants.Cmd_JobCommit.getZwCommandVal()){
            String clientIp = agentLinkManager.getClientIpByAgentId(tcpData.getAgentId());
            AssertUtils.hasText(clientIp,"clientIp offline by agentId["+tcpData.getAgentId()+"],break.");
        }
    }

    public ZwCommPacket sendZwPkg(ZwCommPacket zwCommPacket,String module, String agentId, SolverInfoBean solverInfo)  {
        logger.info("ip:{},port:{}", solverInfo.getIp(),solverInfo.getPort());
        ZwTcpClient idleZwTcpClient = (ZwTcpClient) zwTcpMultiClient.getByAgentIdAndIp(module,agentId,solverInfo);
        AssertUtils.notNull(idleZwTcpClient,new TcpException(MqDataStateConstants.TCP_NULL,"连接实例为空"));
        short cmd = zwCommPacket.getHead().getCmd();
        logger.info("receive cmd from c#, cmd is {}",cmd);
        if (cmd == ActionConstants.Cmd_ClusterInfoQuery.getZwCommandVal()){
            // 需要同步发送
            ZwCommPacket response = idleZwTcpClient.request(zwCommPacket, 30, true);
            logger.info("send response to c#>>>>>>>");
            AssertUtils.notNull(response,new TcpException(MqDataStateConstants.TCP_TIMEOUT,"请求超时"));
            return response;
        }else {
            idleZwTcpClient.sendZwPkg(zwCommPacket);
        }
        return null;
    }


    public MQDataAble genMqQueueData(String module,long queueIndex,String agentId){
        return null;
    }


    @Override
    public String getModuleName() {
        return SysModuleEnum.SIMULATION.getName();
    }

}